#include "serial.h"
#include <stdio.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>  //UNIX标准函数定义
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //文件控制定义
#include <termios.h>  //PPSIX终端控制定义
#include <errno.h>    //错误号定义
#include <pthread.h>

#define P(func) do{perror("func");}while(0)

int serial_init()
{
    int fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY);
    if(-1 == fd)
    {
        P(open);
        return -1;
    }

    struct termios options = {0};
    if(tcgetattr( fd,&options)  !=  0)
    {
        P(SetupSerial);
        return -1;
    }
    cfsetispeed(&options, B115200);		//输出波特率
    cfsetospeed(&options, B115200);		//输入波特率

    options.c_cflag |= CLOCAL|CREAD;  	//忽略modem控制线，使能接收
    options.c_cflag |= CS8;				//8位数据位
    options.c_cflag &= ~CRTSCTS;		//禁用硬件流控
    options.c_cflag &= ~PARENB; 		//清除校验位 PARODD
    options.c_cflag &= ~CSTOPB; 		//一位停止位

    options.c_oflag &= ~(ONLCR | OCRNL);
    options.c_oflag &= ~(ONLCR | OCRNL | ONOCR | ONLRET); //将输出的回车转化成换行

    options.c_iflag &= ~(IXON | IXOFF | IXANY); //禁用流控
    options.c_iflag &= ~(INLCR | ICRNL | IGNCR);//将输入的回车转化成换行
    options.c_iflag &= ~(BRKINT | INPCK | ISTRIP);//ICRNL 将输入的回车转化成换行（如果IGNCR未设置的情况下）
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//禁用终端回显等

    options.c_cc[VTIME] = 1; /* 读取一个字符等待0*(0/10)s */
    options.c_cc[VMIN] = 1; /* 读取字符的最少个数为0 */

    tcflush(fd,TCIFLUSH);
    if (tcsetattr(fd,TCSANOW,&options) != 0)
    {
        P(com set error!\n);
        return -1;
    }
    return fd;
}

int serial_send(int fd, unsigned char *buf, int count)
{
    int ret;
    int total = 0;
    while (total != count) 
    {
        ret = write(fd, buf + total, count - total);
        if (ret == -1) 
        {
            perror("serial_send");
            break;
        } else
            total += ret;
    }	
    return total;
}

int serial_recv(int fd, char *buf, int count,int len_buf)
{
    int ret;
    int total = 0;	
    while (total != count) 
    {
        ret = read(fd, buf + total, count - total);
        if (ret == -1)
        {
            perror("serial_recv");
            break;
        } 
        else if (ret == 0) 
        {
            fprintf(stdout, "serial->recv: timeout or end-of-file\n");
            break;
        } else
            total += ret;
    }
    int i = 0;
    for (i = 0; i < len_buf; i++)
    {
        printf("%.2x ", buf[i]);
    }
    printf("\n");
    
    return total;
}

int serial_exit(int fd)
{
    if (close(fd)) {
        perror("serial->exit");
        return -1;
    }
    return 0;
}
